package jscontrol

import (
	"MqttCloudProtocolServer/ProtocolServer/scriptmanager/modulelib"
	"errors"

	"github.com/dop251/goja"
	"github.com/wonderivan/logger"
)

//TCPModule 导入JS的TCP类库
type TCPModule struct {
	tpcServer      *modulelib.TCPServer
	receiveCallbak goja.Callable
	acceptCallbak  goja.Callable
	jsTCP          *goja.Object
	runtime        *goja.Runtime
}

//CreateTCPModule fun
func CreateTCPModule(runtime *goja.Runtime) *goja.Object {
	content := new(TCPModule)
	content.tpcServer = new(modulelib.TCPServer)
	jsTCP := runtime.NewObject()
	err := jsTCP.Set("Init", content.init)
	if err != nil {
		logger.Error(err)
		return nil
	}
	err = jsTCP.Set("Send", content.send)
	if err != nil {
		logger.Error(err)
		return nil
	}
	err = jsTCP.Set("Close", content.close)
	if err != nil {
		logger.Error(err)
		return nil
	}
	err = jsTCP.Set("ReceiveCallbak", content.setReceiveCallbak)
	if err != nil {
		logger.Error(err)
		return nil
	}
	err = jsTCP.Set("AcceptCallbak", content.setAcceptCallbak)
	if err != nil {
		logger.Error(err)
		return nil
	}
	content.jsTCP = jsTCP
	content.runtime = runtime
	return jsTCP
}
func (_this *TCPModule) init(call goja.FunctionCall) goja.Value {
	if len(call.Arguments) < 3 {
		return GetFromResAndErr(false, errors.New("参数长度错误"), _this.runtime)
	}
	host, err := GetStringFromArgument(call.Argument(0))
	if err != nil {
		return GetFromResAndErr(false, err, _this.runtime)
	}
	port, err := GetIntFromArgument(call.Argument(1))
	if err != nil {
		return GetFromResAndErr(false, err, _this.runtime)
	}
	signle, err := GetBoolFromArgument(call.Argument(2))
	if err != nil {
		return GetFromResAndErr(false, err, _this.runtime)
	}
	_this.tpcServer.Init(host, port, signle)
	_this.tpcServer.SetAcceptEvent(func(key string) {
		if _this.acceptCallbak == nil {
			logger.Info("未设置连接成功回调函数")
			return
		}
		_this.acceptCallbak(_this.jsTCP, _this.runtime.ToValue(key))
	})
	_this.tpcServer.SetReceivEvent(func(key string, buffer []uint8) {
		if _this.receiveCallbak == nil {
			logger.Info("未设置接收回调函数")
			return
		}
		_this.receiveCallbak(_this.jsTCP, _this.runtime.ToValue(key), _this.runtime.ToValue(buffer))
	})
	return GetFromResAndErr(true, nil, _this.runtime)
}
func (_this *TCPModule) send(call goja.FunctionCall) goja.Value {
	if len(call.Arguments) < 1 {
		return GetFromResAndErr(false, errors.New("参数长度错误"), _this.runtime)
	}
	key, err := GetStringFromArgument(call.Argument(0))
	if err != nil {
		return GetFromResAndErr(false, err, _this.runtime)
	}
	buffer, err := GetBufferFromArgument(call.Argument(1))
	if err != nil {
		return GetFromResAndErr(false, err, _this.runtime)
	}
	_, err = _this.tpcServer.Send(key, buffer)
	return GetFromResAndErr(err == nil, err, _this.runtime)
}
func (_this *TCPModule) setReceiveCallbak(call goja.FunctionCall) goja.Value {
	if len(call.Arguments) < 1 {
		return GetFromResAndErr(false, errors.New("参数长度错误"), _this.runtime)
	}
	callbakFun, ok := goja.AssertFunction(call.Argument(0))
	if !ok {
		return GetFromResAndErr(false, errors.New("设置接收回调失败"), _this.runtime)
	}
	_this.receiveCallbak = callbakFun
	return GetFromResAndErr(true, nil, _this.runtime)
}
func (_this *TCPModule) setAcceptCallbak(call goja.FunctionCall) goja.Value {
	if len(call.Arguments) < 1 {
		return GetFromResAndErr(false, errors.New("参数长度错误"), _this.runtime)
	}
	callbakFun, ok := goja.AssertFunction(call.Argument(0))
	if !ok {
		return GetFromResAndErr(false, errors.New("设置连接成功回调失败"), _this.runtime)
	}
	_this.acceptCallbak = callbakFun
	return GetFromResAndErr(true, nil, _this.runtime)
}
func (_this *TCPModule) close(call goja.FunctionCall) goja.Value {
	err := _this.tpcServer.Close()
	return GetFromResAndErr(err == nil, err, _this.runtime)
}
